home *** CD-ROM | disk | FTP | other *** search
- /*
- File: WinPopM.cpp
-
- Contains: The Document Path pop-up menu
-
- Owned by: Jens Alfke
-
- Copyright: © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 6/4/96 EL 1335851: Release string from GetEditor.
- <10> 10/4/95 jpa Fixed ref-count bugs in WalkFrameHierarchy.
- [1285639]
- <9> 8/29/95 jpa Fixes for Univ Hdrs 2.1 & CW7 [1279173]
- <8> 8/25/95 JP 1254840: ODGetIconFamily part to frame
- fallout
- <7> 8/16/95 NP 1274946: ErrorDef.idl problems. Add include
- file.
- <6> 8/15/95 CC 1275241: Added #include of Aliases.h
- <5> 8/8/95 jpa Fixed DebugStr [1265584]
- <4> 7/26/95 DM #1270320: Memory leak fixes: dispose desc
- in RevealFinderIcon
- <3> 6/29/95 jpa Use container ID to get document file spec.
- [1261806] Add "Desktop" to pop-up when doc
- path ends at desktop. [1262681]
- <2> 6/25/95 TÇ 1242642 BB: Turn on ODDebug warning if
- refcount is wrong in
- ODRefCntObjectsomUninit.
- <1> 6/19/95 jpa first checked in
-
- In Progress:
-
- */
-
-
- #ifndef _WINPOPM_
- #include "WinPopM.h"
- #endif
-
- #ifndef _WINDOW_
- #include "Window.xh"
- #endif
-
- #ifndef _WINSTAT_
- #include "WinStat.xh"
- #endif
-
- #ifndef _DISPTCH_
- #include "Disptch.xh"
- #endif
-
- #ifndef _UIDEFS_
- #include "UIDefs.h"
- #endif
-
- #ifndef _DOCUMENT_
- #include <Document.xh>
- #endif
-
- #ifndef _FRAME_
- #include <Frame.xh>
- #endif
-
- #ifndef _ODCTR_
- #include <ODCtr.xh>
- #endif
-
- #ifndef _ODSTOR_
- #include <ODStor.xh>
- #endif
-
- #ifndef _PARTWRAP_
- #include <PartWrap.xh>
- #endif
-
- #ifndef _LINKMGR_
- #include <LinkMgr.xh>
- #endif
-
- #ifndef _DRAGDRP_
- #include <DragDrp.xh>
- #endif
-
- #ifndef _SHAPE_
- #include <Shape.xh>
- #endif
-
- #ifndef _NMSPCMG_
- #include <NmSpcMg.xh>
- #endif
-
- #ifndef _VALUENS_
- #include <ValueNS.xh>
- #endif
-
- #ifndef _STDDEFS_
- #include <StdDefs.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef _BNDNSUTL_
- #include <BndNSUtl.h>
- #endif
-
- #ifndef _INFOUTIL_
- #include <InfoUtil.h>
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef _PLFMFILE_
- #include <PlfmFile.h>
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h> // For BitTst()
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifndef __DEVICES__
- #include <Devices.h>
- #endif
-
- #include <stdlib.h>
-
- typedef Handle IconSuite;
-
-
- const ODSShort kUseSpecificScript = 0x1c; // Script mgr code for menu items
-
- const short kFloppyDriverRefNum = 0xFFFB; // Floppy (.SONY) driver refnum
-
- const Point kMenuOffset = {1,-36}; // Menu offset from window title
-
- const short kDefaultDocIconID = 128; // A default OpenDoc part icon (small sizes only)
- const short kPartPopUpMenuID = 9000; // Menu ID of title-bar pop-up
- const short kGenericPartSICNID= 263; // SICN ID of generic part icon
-
- const short kKindIconBase = 7; // Icon# (rsrc ID -256) of 1st reserved icon for parts
- const short kMaxNKindIcons = 5;
-
-
- static short gNKindIcons;
- static ODType gIconKind[kMaxNKindIcons];
-
-
- static short TitlePopUpSelect( WindowPtr w, const FSSpec &doc, MenuHandle m, Point where );
- static ODFrame* WalkFrameHierarchy( Environment *, ODFrame *, MenuHandle, short stopAtItem =32767 );
- static OSErr RevealFinderIcon( const FSSpec &itemToReveal, const FSSpec &parentFolder );
- static OSErr GetParentID(short vRefNum,
- long dirID,
- StringPtr name,
- long *parID);
- static OSErr GetDirName(short vRefNum,
- long dirID,
- StringPtr name);
- static OSErr FSpGetFileLocation(short refNum,
- FSSpec *spec);
- static ODBoolean VolumeIsFloppy( short vRefNum );
-
-
- #pragma segment PathPopUp
-
-
- //==============================================================================
- #pragma mark UTILITIES
- //==============================================================================
-
-
- static ODDocument*
- GetDocument( Environment *ev, ODWindow *w )
- {
- return w->GetDraft(ev)->GetDocument(ev);
- }
-
- static void
- GetDocumentFileSpec( Environment *ev, ODWindow *w, FSSpec &fss )
- {
- TempODContainerIDStruct id(GetDocument(ev,w)->GetContainer(ev)->GetID(ev));
- ASSERT(id->_length>=8 && id->_length<=sizeof(FSSpec), kODErrAssertionFailed);
- ODBlockMove(id->_buffer,&fss,sizeof(FSSpec));
- }
-
- static ODSession*
- GetSession( Environment *ev, ODDocument *document )
- {
- return document->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
- }
-
- static ODSession*
- GetSession( Environment *ev, ODWindow *window )
- {
- return GetSession(ev,GetDocument(ev,window));
- }
-
- static ODSession*
- GetSession( Environment *ev, ODPersistentObject *po )
- {
- return po->GetStorageUnit(ev)->GetSession(ev);
- }
-
-
- //==============================================================================
- #pragma mark TITLE-BAR CLICKS
- //==============================================================================
-
-
- /////////////////////////////////////////////////////////////
- // TrackWindowPathPopUp //
- // Called from any click in title bar //
- /////////////////////////////////////////////////////////////
- ODBoolean
- TrackWindowPathPopUp( Environment *ev, ODWindow *w, Point where )
- {
- KeyMap keys;
- GetKeys(keys);
-
- if( ! BitTst(&keys,0x30) ) // Must be holding down Command key
- return kODFalse;
-
- WindowPtr wp = w->GetPlatformWindow(ev);
- if( !((WindowPeek)wp)->hilited )
- return kODFalse; // Window must be active
-
- if( w->IsFloating(ev) || !w->GetDraft(ev) ) // Must not be floating window
- return kODFalse; // and must have a draft
-
- ODFrame *frame = w->GetRootFrame(ev); // Must have an OpenDoc frame
- if( !frame )
- return kODFalse;
-
- Str255 title;
- GetWTitle(wp,title);
- SetPort(LMGetWMgrPort());
- short titleWidth = StringWidth(title);
- SetPort(wp);
- GlobalToLocal(&where);
-
- if( abs(where.h-(wp->portRect.right-wp->portRect.left)/2) <= titleWidth/2 ) {
-
- // Where does the pop-up go?
- Point popWhere;
- popWhere.h = (wp->portRect.left+wp->portRect.right-titleWidth)/2 + kMenuOffset.h;
- LocalToGlobal(&popWhere);
- popWhere.v = (**((WindowPeek)wp)->strucRgn).rgnBBox.top + kMenuOffset.v;
-
- CUsingLibraryResources u;
-
- // Build the pop-up:
- MenuHandle m = NewMenu(kPartPopUpMenuID,"\p");
- if( !m ) return kODTrue;
- ODFrame *f1 = WalkFrameHierarchy(ev,frame,m);
- ODReleaseObject(ev,f1);
-
- // Pop it up:
- FSSpec fss;
- GetDocumentFileSpec(ev,w,fss);
- short item= TitlePopUpSelect(wp, fss, m, popWhere);
-
- // If user selected a parent frame, show its window & select the frame:
- if( item>1 && item<=CountMItems(m) ) {
- TempODFrame f2 = WalkFrameHierarchy(ev,frame,kODNULL,item);
- TempODWindow w = f2->AcquireWindow(ev);
- w->Select(ev);
- }
-
- DisposeMenu(m);
- return kODTrue;
-
- } else
- return kODFalse;
- }
-
-
- //==============================================================================
- #pragma mark BUILDING THE POP-UP
- //==============================================================================
-
-
- inline void
- ClearPartMenuIcons( )
- {
- gNKindIcons = 1;
- gIconKind[0] = kODNULL; // Reserve one icon as a default
- }
-
-
- /////////////////////////////////////////////////////////////
- // GetPartMenuIcon //
- // Return an icon ID to use for a part //
- /////////////////////////////////////////////////////////////
- static short
- GetPartMenuIcon( Environment *ev, ODFrame *frame )
- {
- TempODPart part = frame->AcquirePart(ev);
- ODType kind = ODGetKind(ev, part);
- short i;
- for( i=0; i<gNKindIcons; i++ )
- if( gIconKind[i]==kind || ODISOStrEqual(gIconKind[i],kind) )
- return kKindIconBase+i; // Already have an icon
- if( gNKindIcons==kMaxNKindIcons )
- return kKindIconBase+0; // Default icon
- else {
- gIconKind[gNKindIcons++] = kind; // Remember a new kind
-
- // A slightly sick way to customize the icon in the pop-up.
- // Get the SICN and copy the appropriate 'ics#' data into it in memory.
- // Since the resource is never written back to disk, and the resource
- // file will be closing right afterwards, this is safe to do:
- IconSuite partIconSuite = ODGetIconFamily(ev, frame);
- if( partIconSuite ) {
- Handle icon;
- (void) GetIconFromSuite(&icon, partIconSuite, 'ics#');
- if( icon ) {
- Handle sicn = Get1Resource('SICN',256+kKindIconBase+i);
- if( sicn )
- ODBlockMove(*icon,*sicn,GetHandleSize(sicn));
- }
- DisposeIconSuite(partIconSuite,true);
- }
- return kKindIconBase+i;
- }
- }
-
-
- /////////////////////////////////////////////////////////////
- // GetNameForPart //
- // Create an IText with a name for this part //
- /////////////////////////////////////////////////////////////
- static ODIText*
- GetNameForPart( Environment *ev, ODPart *part )
- {
- // Come up with something to call the part: either its real name,
- // its editor name, or at last resort its SOM class name.
-
- ODIText* partName = ODGetPOName(ev, part, kODNULL);
- if( partName )
- return partName;
-
- // Part itself has no name, so use editor name:
- TempODEditor editorID = ((ODPartWrapper*)part)->GetEditor(ev);
- if( GetUserEditorFromEditor(GetSession(ev,part)->GetNameSpaceManager(ev), editorID, &partName) )
- return CopyIText(partName);
-
- // Could not get editor name, resort to SOM classname:
- char *namePtr = editorID;
- char *lastcolon = strrchr(namePtr,':');
- if( lastcolon )
- namePtr = lastcolon+1; // Use last segment of name
- return CreateITextCString(smRoman,langEnglish,namePtr);
- }
-
-
- /////////////////////////////////////////////////////////////
- // WalkFrameHierarchy //
- // Make the frame-hierarchy pop-up menu //
- /////////////////////////////////////////////////////////////
- static ODFrame*
- WalkFrameHierarchy( Environment *ev, ODFrame *startFrame, MenuHandle m, short stopAtItem )
- {
- /* This has two purposes. (1) it builds the initial pop-up menu for the title-bar.
- The HFS path of the document will be appended to this before the user sees it.
- (2) If the user chooses one of the items added to the menu by this routine,
- it's called again, with no menu but stopAtItem set, to determine which frame
- corresponded to that item.
- ** You must release the frame returned by this function **
- */
-
- ClearPartMenuIcons();
-
- startFrame->Acquire(ev); // It will be released later
- TempODFrame frame = startFrame; // Reference to current frame, on our walk
- TempODFrame parent = kODNULL; // Reference to its parent frame
-
- while( frame ) {
- if( --stopAtItem <= 0 )
- break;
-
- // Find the parent frame, going to the parent window if necessary:
- {
- TempODWindow frameWindow = kODNULL;
- parent = frame->AcquireContainingFrame(ev);
-
- if( !parent ) {
- frameWindow = frame->AcquireWindow(ev);
- parent = frameWindow->AcquireSourceFrame(ev);
- if( parent ) {
- ODFrame *parent2 = parent->AcquireContainingFrame(ev); // -- TÇ: swapping refcounts here
- parent->Release(ev); // -- TÇ: swapping refcounts here
- parent = parent2;
- }
- }
-
- if( m ) {
- // Add menu item for this frame:
- TempODPart part = frame->AcquirePart(ev);
- Str255 nameStr;
-
- AppendMenu(m,"\pX");
- short mItem = CountMItems(m);
- SetItemIcon(m,mItem,GetPartMenuIcon(ev, frame));
- SetItemCmd(m,mItem,0x1E);
-
- if( frameWindow ) // Use window title if possible
- GetWTitle(frameWindow->GetPlatformWindow(ev),nameStr);
- else
- nameStr[0] = 0;
-
- if( nameStr[0] == 0 ) {
- ODIText *t = GetNameForPart(ev,part); // Else use part's name
- if( t ) {
- GetITextPString(t,nameStr);
- short s = GetITextScriptCode(t);
- if( s != GetScriptManagerVariable(smSysScript) ) {
- SetItemCmd(m, mItem, kUseSpecificScript); // Force script
- SetItemIcon(m, mItem, s);
- }
- DisposeIText(t);
- }
- }
- SetMenuItemText(m,mItem,nameStr);
- }
-
- frame.Release(); // Forget current frame,
- frame = (ODFrame*)parent; // switch to parent
- parent = kODNULL;
- }
- }
-
- return frame.DontRelease(); // Return frame, don't release it (caller must do so)
- }
-
-
- /*=======================================================================================*/
- #pragma mark TITLE POP-UP
- /*=======================================================================================*/
-
-
- const short kTitlePopUpMenuID = 30000; // Created on the fly
- const long kRootDir = 2;
-
- // 'SICN' resource IDs for the icons in the path menu.
- // BuildPathMenu assumes these icons are in the resource chain and not overridden
- // by any other icons.
- enum {
- kDocumentSICN = 257, /*unused*/
- kFolderSICN,
- kTrashSICN, /*unused*/
- kDiskSICN,
- kFloppySICN,
- kDesktopSICN
- };
-
-
- /////////////////////////////////////////////////////////////
- // BuildPathMenu //
- // Make the pop-up menu for the HFS path //
- /////////////////////////////////////////////////////////////
- static void
- BuildPathMenu( FSSpec *spec, MenuHandle m, short stopAtItem )
- {
- // This routine assumes that spec is a file, not a directory.
-
- stopAtItem++;
-
- short vol = spec->vRefNum;
- long dir = 0;
-
- long desktopDir;
- short foundVol;
- THROW_IF_ERROR( FindFolder(vol,kDesktopFolderType, true, &foundVol,&desktopDir) );
-
- for( short item=1; item<stopAtItem; item++ ) {
- // Get the name of the current' item's parent dir, and the parent ID of that:
- long parent;
- dir = spec->parID;
- if( GetParentID(vol,spec->parID,NULL, &parent) != noErr ) // Get next parent
- break;
- if( GetDirName(vol,spec->parID, spec->name) != noErr ) // Get name of current parent
- break;
- spec->parID = parent;
-
- // Add the current item to the menu:
- if( m ) {
- AppendMenu(m,"\pX"); // Two steps in case...
- short mItem = CountMItems(m);
- if( dir==desktopDir )
- ODGetString(spec->name,kODDesktopTitleStrID);
- SetMenuItemText(m,mItem,spec->name); // ...spec->name contains meta-chars
- short icon;
- if( dir==desktopDir )
- icon = kDesktopSICN - 256;
- else if( dir!=kRootDir )
- icon = kFolderSICN - 256;
- else if( VolumeIsFloppy(vol) )
- icon = kFloppySICN - 256;
- else
- icon = kDiskSICN - 256;
- SetItemIcon(m,mItem,icon);
- SetItemCmd(m,mItem,0x1E);
- }
-
- // Quit when we reach the desktop or volume root:
- if( dir==desktopDir || dir==kRootDir )
- break;
- }
- }
-
-
- /////////////////////////////////////////////////////////////
- // TitlePopUpSelect //
- // Big kahuna that runs the pop-up //
- /////////////////////////////////////////////////////////////
- static short
- TitlePopUpSelect( WindowPtr w, const FSSpec &doc, MenuHandle m, Point where )
- {
- short prevItems = CountMItems(m);
- FSSpec itemSpec = doc;
-
- BuildPathMenu(&itemSpec,m,32000); // Append path to file to the menu
-
- InsertMenu(m,-1);
- short item= (short) PopUpMenuSelect(m,where.v,where.h, 1); // Shazam! Pop up the menu
- DeleteMenu((**m).menuID);
-
- for( short count = CountMItems(m); count>prevItems; count-- ) // Restore to prev state
- DeleteMenuItem(m,count);
-
- if( item > prevItems && item>1 ) { // Item 1 is just the document itself
- FSSpec parentSpec = doc;
- BuildPathMenu(&parentSpec,NULL,item-prevItems); // Folder to open
- itemSpec = doc;
- BuildPathMenu(&itemSpec,NULL,item-prevItems-1); // Item in folder to reveal
- OSErr err = RevealFinderIcon(itemSpec,parentSpec); // Tell the Finder to reveal it
- }
- return item;
- }
-
-
- /*============================================================================================*/
- #pragma mark TALKING TO THE FINDER
- /*============================================================================================*/
-
-
- #define kFinderSignature 'MACS'
- #define kFinderEventClass 'FNDR'
- #define kFinderRevealEvent 'srev'
- #define keyFinderSelection 'fsel'
-
-
- /////////////////////////////////////////////////////////////
- // CreateFinderRevealEvent //
- // Build an AEvt for revealing an item //
- /////////////////////////////////////////////////////////////
- static OSErr
- CreateFinderRevealEvent( const FSSpec *itemToReveal, const FSSpec *parentFolder, AEDesc *evt )
- {
- OSErr err;
- OSType finderSignature = kFinderSignature;
- AliasHandle alias = NULL;
- AEDesc target = {typeNull,NULL};
- AEDescList list = {typeNull,NULL};
-
- evt->dataHandle = NULL;
-
- err= AECreateDesc(typeApplSignature,&finderSignature,sizeof(OSType), &target);
- if( err ) goto exit;
- err= AECreateAppleEvent(kFinderEventClass, kFinderRevealEvent,
- &target, kAutoGenerateReturnID, kAnyTransactionID,
- evt);
- if( err ) goto exit;
- AEDisposeDesc(&target);
-
- err= NewAlias(NULL,parentFolder,&alias); // Parent folder param must be full alias
- if( err ) goto exit;
- HLockHi((Handle)alias);
- err= AEPutParamPtr(evt,keyDirectObject, typeAlias,*alias,GetHandleSize((Handle)alias));
- DisposeHandle((Handle)alias);
- alias = NULL;
-
- err= NewAliasMinimal(itemToReveal,&alias);
- if( err ) goto exit;
-
- err= AECreateList(NULL,0,false, &list);
- if( err ) goto exit;
- err= AEPutPtr(&list,1,typeAlias,*alias,GetHandleSize((Handle)alias));
- if( err ) goto exit;
-
- err= AEPutParamDesc(evt,keyFinderSelection, &list);
- if( err ) goto exit;
-
- exit:
- AEDisposeDesc(&target);
- AEDisposeDesc(&list);
- if( alias ) DisposeHandle((Handle)alias);
- if( err )
- AEDisposeDesc(evt);
-
- return err;
- }
-
-
- /////////////////////////////////////////////////////////////
- // ActivateFinder //
- // Make the Finder the front process //
- /////////////////////////////////////////////////////////////
- static void
- ActivateFinder( )
- {
- OSErr err;
- ProcessSerialNumber process = {0,kNoProcess};
- for(;;) {
- err= GetNextProcess(&process);
- if( err )
- break;
- ProcessInfoRec info;
- info.processInfoLength = sizeof(info);
- info.processName = NULL;
- info.processAppSpec = NULL;
- err= GetProcessInformation(&process,&info);
- if( err )
- break;
- if( info.processSignature == kFinderSignature ) {
- err= SetFrontProcess(&process);
- if( err )
- break;
- else
- return;
- }
- }
- WARN("Couldn't activate Finder!");
- }
-
-
- /////////////////////////////////////////////////////////////
- // RevealFinderIcon //
- // Send the Finder an AEvt for revealing an item //
- /////////////////////////////////////////////////////////////
- static OSErr
- RevealFinderIcon( const FSSpec &itemToReveal, const FSSpec &parentFolder )
- {
- OSErr err;
- AppleEvent evt, reply;
-
- err= CreateFinderRevealEvent(&itemToReveal,&parentFolder, &evt);
- TempAEDesc tempErr(&evt); // make sure it is disposed
- if( !err )
- err= AESend(&evt,&reply, kAENoReply|kAEAlwaysInteract|kAECanSwitchLayer,
- kAENormalPriority, kNoTimeOut, NULL,NULL);
- if( !err )
- ActivateFinder();
- return err;
- }
-
-
- /*============================================================================================*/
- #pragma mark SWIPED FROM MOREFILES 1.2.1
- /*============================================================================================*/
-
-
- static OSErr GetParentID(short vRefNum,
- long dirID,
- StringPtr name,
- long *parID)
- {
- CInfoPBRec pb;
- OSErr error;
-
- pb.hFileInfo.ioNamePtr = name;
- pb.hFileInfo.ioVRefNum = vRefNum;
- pb.hFileInfo.ioDirID = dirID;
- pb.hFileInfo.ioFDirIndex = name ?0 :-1;
- error = PBGetCatInfoSync(&pb);
- *parID = pb.hFileInfo.ioFlParID;
- return ( error );
- }
-
-
- static OSErr GetDirName(short vRefNum,
- long dirID,
- StringPtr name)
- {
- CInfoPBRec pb;
-
- pb.hFileInfo.ioNamePtr = name;
- pb.hFileInfo.ioVRefNum = vRefNum;
- pb.hFileInfo.ioDirID = dirID;
- pb.hFileInfo.ioFDirIndex = -1; /* get information about ioDirID */
- return ( PBGetCatInfoSync(&pb) );
- }
-
-
- static OSErr GetFileLocation(short refNum,
- short *vRefNum,
- long *dirID,
- StringPtr fileName)
- {
- FCBPBRec pb;
- OSErr error;
-
- pb.ioNamePtr = fileName;
- pb.ioVRefNum = 0;
- pb.ioRefNum = refNum;
- pb.ioFCBIndx = 0;
- error = PBGetFCBInfoSync(&pb);
- *vRefNum = pb.ioFCBVRefNum;
- *dirID = pb.ioFCBParID;
- return ( error );
- }
-
-
- static OSErr FSpGetFileLocation(short refNum,
- FSSpec *spec)
- {
- return ( GetFileLocation(refNum, &(spec->vRefNum), &(spec->parID), spec->name) );
- }
-
-
- static OSErr FindDrive(StringPtr pathname,
- short vRefNum,
- DrvQElPtr *driveQElementPtr)
- {
- OSErr result;
- Str255 tempPathname;
- HParamBlockRec hPB;
- short driveNumber;
-
- *driveQElementPtr = NULL;
-
- /* First, use PBHGetVInfo to determine the volume */
- hPB.volumeParam.ioVRefNum = vRefNum;
- if ( pathname == NULL )
- {
- hPB.volumeParam.ioNamePtr = NULL;
- hPB.volumeParam.ioVolIndex = 0; /* use ioVRefNum only */
- }
- else
- {
- ODBlockMove(pathname, tempPathname, pathname[0] + 1); /* make a copy of the string and */
- hPB.volumeParam.ioNamePtr = (StringPtr)tempPathname; /* use the copy so original isn't trashed */
- hPB.volumeParam.ioVolIndex = -1; /* use ioNamePtr/ioVRefNum combination */
- }
- result = PBHGetVInfoSync(&hPB);
- if ( result == noErr )
- {
- /*
- ** The volume can be either online, offline, or ejected. What we find in
- ** ioVDrvInfo and ioVDRefNum will tell us which it is.
- ** See Inside Macintosh: Files page 2-80 and the Technical Note
- ** "FL 34 - VCBs and Drive Numbers : The Real Story"
- ** Where we get the drive number depends on the state of the volume.
- */
- if ( hPB.volumeParam.ioVDrvInfo != 0 )
- {
- /* The volume is online and not ejected */
- /* Get the drive number */
- driveNumber = hPB.volumeParam.ioVDrvInfo;
- }
- else
- {
- /* The volume's is either offline or ejected */
- /* in either case, the volume is NOT online */
-
- /* Is it ejected or just offline? */
- if ( hPB.volumeParam.ioVDRefNum > 0 )
- {
- /* It's ejected, the drive number is ioVDRefNum */
- driveNumber = hPB.volumeParam.ioVDRefNum;
- }
- else
- {
- /* It's offline, the drive number is the negative of ioVDRefNum */
- driveNumber = (short)-hPB.volumeParam.ioVDRefNum;
- }
- }
-
- /* Get pointer to first element in drive queue */
- *driveQElementPtr = (DrvQElPtr)(GetDrvQHdr()->qHead);
-
- /* Search for a matching drive number */
- while ( (*driveQElementPtr != NULL) && ((*driveQElementPtr)->dQDrive != driveNumber) )
- {
- *driveQElementPtr = (DrvQElPtr)(*driveQElementPtr)->qLink;
- }
-
- if ( *driveQElementPtr == NULL )
- {
- /* This should never happen since every volume must have a drive, but... */
- result = nsDrvErr;
- }
- }
-
- return ( result );
- }
-
- static ODBoolean VolumeIsFloppy( short vRefNum )
- {
- DrvQElPtr q;
- return FindDrive(NULL,vRefNum,&q)==noErr && q->dQRefNum==kFloppyDriverRefNum;
- }
-